﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using Xenta.Utils;

namespace Xenta.Web.Views
{
    /// <summary>
    /// Represents the extended view.
    /// </summary>
    /// <typeparam name="TModel">The type of model.</typeparam>
    public abstract class ExtView<TModel> : WebViewPage<TModel>
    {
        #region Constants

        private static readonly Regex PATTERN_TYPE =
            new Regex(@"_Page(_Areas_(?<area>[^_]+){1})?_Views_(?<path>[^_]+){1}_(?<view>\w+){1}_cshtml",
                RegexOptions.Compiled |
                RegexOptions.CultureInvariant |
                RegexOptions.IgnoreCase);

        #endregion

        #region Properties

        /// <summary>
        /// Gets the service associated with the view.
        /// </summary>
        public Service Svc
        {
            get
            {
                return Context.Svc();
            }
        }

        /// <summary>
        /// Gets a randomly generated view identifier.
        /// </summary>
        public string ViewID
        {
            get
            {
                return GetType().Name
                    .GetHashCode()
                    .ToString("x8");
            }
        }

        /// <summary>
        /// Gets the collection of required bundles.
        /// </summary>
        public IEnumerable<String> Bundles
        {
            get
            {
                return Context.Items.Contains("Bundles") ? 
                    Context.Items["Bundles"] as IEnumerable<String> : 
                    Enumerable.Empty<String>();
            }
        }

        /// <summary>
        /// Gets the resource for the current view.
        /// </summary>
        public Res Res
        {
            get
            {
                var value = Res.In(Context
                    .ApplicationInstance
                    .GetType()
                    .BaseType
                    .Name);
                var name = GetType().Name;
                var m = PATTERN_TYPE.Match(name);
                if(!m.Success)
                    return value.Of(name);
                if(m.Success)
                {
                    if(m.Groups["area"].Success)
                        value = value.Of(m.Groups["area"].Value);
                    value = value.Of(m.Groups["path"].Value);
                    value = value.Of(m.Groups["view"].Value);
                }
                return value;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Include the bundle.
        /// </summary>
        /// <param name="bunlde">The name of a bundle.</param>
        public void Bundle(string bunlde)
        {
            if(!Context.Items.Contains("Bundles"))
                Context.Items["Bundles"] = new List<String>();

            var bundles = Context.Items["Bundles"] 
                as List<String>;
            if(bundles.Contains(bunlde))
                return;
            bundles.Add(bunlde);
        }

        /// <summary>
        /// Gets the entry of associated language pack 
        /// using the provided key, then using the entry 
        /// as a format string.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="args">The formatting arguments.</param>
        /// <returns>The entry string.</returns>
        public string T(string key, params object[] args)
        {
            string value = Svc.Translate(key);
            if(args != null && args.Length != 0)
                value = String.Format(value, args);
            return value;
        }

        /// <summary>
        /// Generates the unique identifier using the custom identifier format
        /// and the view identifier.
        /// </summary>
        /// <param name="fmt">The custom identifier format.</param>
        /// <param name="args">The formatting arguments.</param>
        /// <returns>The generated identifier.</returns>
        public string ID(string fmt, params object[] args)
        {
            string value = String.Format("{0}_{1}", fmt, ViewID);
            if(args != null && args.Length != 0)
                value = String.Format(value, args);
            return value;
        }

        #endregion
    }
}